package com.hunit.mqtt_dome.emqx;

import com.hunit.mqtt_dome.properties.MqttProperties;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * @Description : MQTT发送客户端
 * @Author : Sherlock
 * @Date : 2023/8/1 16:30
 */
@Component
public class MqttSendClient {

    private static final Logger logger = LoggerFactory.getLogger(MqttSendClient.class);

    @Autowired
    private MqttSendCallBack mqttSendCallBack;

    @Autowired
    private MqttProperties mqttProperties;
    
    private MqttClient mqttClient;
    private boolean connected = false;

    /**
     * 连接MQTT服务器
     * 
     * @return 是否连接成功
     */
    public boolean connect() {
        if (connected && mqttClient != null && mqttClient.isConnected()) {
            return true;
        }
        
        try {
            String clientId = mqttProperties.getClientId() + "_sender_" + UUID.randomUUID().toString().substring(0, 8);
            mqttClient = new MqttClient(mqttProperties.getHostUrl(), clientId, new MemoryPersistence());
            MqttConnectOptions options = new MqttConnectOptions();
            options.setUserName(mqttProperties.getUsername());
            options.setPassword(mqttProperties.getPassword().toCharArray());
            options.setConnectionTimeout(mqttProperties.getTimeout());
            options.setKeepAliveInterval(mqttProperties.getKeepAlive());
            options.setCleanSession(mqttProperties.getCleanSession());
            options.setAutomaticReconnect(mqttProperties.getReconnect());
            // 设置回调
            mqttClient.setCallback(mqttSendCallBack);
            mqttClient.connect(options);
            connected = true;
            logger.info("MQTT发送客户端连接成功，clientId: {}", clientId);
            return true;
        } catch (Exception e) {
            connected = false;
            logger.error("MQTT发送客户端连接失败，错误信息: {}", e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 发布消息
     *
     * @param retained 是否保留
     * @param topic 主题，格式： server:${env}:report:${topic}
     * @param content 消息内容
     * @return 是否发送成功
     */
    public boolean publish(boolean retained, String topic, String content) {
        if (!connected) {
            if (!connect()) {
                return false;
            }
        }
        
        try {
            MqttMessage message = new MqttMessage();
            message.setQos(mqttProperties.getQos());
            message.setRetained(retained);
            message.setPayload(content.getBytes());
            
            mqttClient.publish(mqttProperties.getServerTopic(topic), message);
            logger.info("消息发送成功，主题: {}, 内容: {}", mqttProperties.getServerTopic(topic), content);
            return true;
        } catch (MqttException e) {
            logger.error("消息发送失败，错误信息: {}", e.getMessage());
            e.printStackTrace();
            
            // 尝试重新连接
            connected = false;
            return false;
        }
    }

    /**
     * 关闭连接
     */
    public void disconnect() {
        try {
            if (mqttClient != null && mqttClient.isConnected()) {
                mqttClient.disconnect();
                mqttClient.close();
                connected = false;
                logger.info("MQTT发送客户端已断开连接");
            }
        } catch (MqttException e) {
            logger.error("MQTT发送客户端断开连接失败，错误信息: {}", e.getMessage());
            e.printStackTrace();
        }
    }
}
